package com.mall.web.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.Bucket;
import com.aliyun.oss.model.Callback;
import com.aliyun.oss.model.Callback.CalbackBodyType;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.CreateBucketRequest;
import com.aliyun.oss.model.ListBucketsRequest;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.OSSObjectSummary;
import com.aliyun.oss.model.ObjectAcl;
import com.aliyun.oss.model.ObjectListing;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;

public class OssUtil {
	
	/*public static String endpoint = "https://oss-cn-shanghai.aliyuncs.com";
	public static String accessKeyId = "LTAImwLn1YWccFoB";
	public static String accessKeySecret = "itfEiqtG9V7KBzesBKWk3BD8jzZlid";
	public static String bucketName = "shaozhong001";*/
	public static String endpoint = "https://oss-cn-shanghai.aliyuncs.com";
	public static String accessKeyId = "LTAI6oUjTJZVzk7x";
	public static String accessKeySecret = "EtAPeYbCAnJid00OsyAJ6FBRB0XY8k";
	public static String bucketName = "shaozhong001";
	
	
	private static final String callbackUrl = "www.baidu.com";
	public static String HTTP_XIE = "/";
	public static String HTTP_HENG = "-";
	
	private static Logger log = LoggerFactory.getLogger(OssUtil.class);
    
	/**
	 * 上传单个文件
	 * @param key
	 * @param inputStream
	 * @throws IOException
	 */
    public static void uploadFileToOSS(String key,InputStream inputStream) throws IOException {
        //创建OSSClient实例
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        try {
            //判断bucket是否存在，不存在则创建
            if (!ossClient.doesBucketExist(bucketName)) {
                // Create a new OSS bucket
            	log.error("Creating bucket " + bucketName );
                ossClient.createBucket(bucketName);
                CreateBucketRequest createBucketRequest= new CreateBucketRequest(bucketName);
                //bucket存储空间有三种访问权限：public-read-write（公共读写）   public-read（公共读，私有写）  private（私有读写）
                createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
                ossClient.createBucket(createBucketRequest);
            }
            //上传文件流
            if(inputStream != null){
            	ossClient.putObject(bucketName, key, inputStream);
            }
          
        } catch (OSSException oe) {
        	log.error("Error code: " + oe.getErrorCode());
        	log.error("Error info: " + oe.getErrorMessage());
        } catch (ClientException ce) {
        	log.error("Error code: " + ce.getErrorCode());
        	log.error("Error info: " + ce.getErrorMessage());
        } finally {
            //关闭ossClient
            ossClient.shutdown();
        }
    }
    
    /**
	 * 完整测试
	 * @param key
	 * @param inputStream
	 * @throws IOException
	 */
    public static void uploadFile(String key,InputStream inputStream) throws IOException {
        //创建OSSClient实例
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        log.error("Getting Started with OSS SDK for Java");
        
        try {
            //判断bucket是否存在，不存在则创建
            if (!ossClient.doesBucketExist(bucketName)) {
                // Create a new OSS bucket
            	log.error("Creating bucket " + bucketName );
                ossClient.createBucket(bucketName);
                CreateBucketRequest createBucketRequest= new CreateBucketRequest(bucketName);
                //bucket存储空间有三种访问权限：public-read-write（公共读写）   public-read（公共读，私有写）  private（私有读写）
                createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
                ossClient.createBucket(createBucketRequest);
            }
            //设置响应请求内返回结果的最大数目500
            ListBucketsRequest listBucketsRequest = new ListBucketsRequest();
            listBucketsRequest.setMaxKeys(500);
            
            //展示buckets列表
            for (Bucket bucket : ossClient.listBuckets()) {
            	log.error(" - " + bucket.getName());
            }
            

            //上传文件流
            //上传回调callback
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, "key", inputStream); 
            Callback callback = new Callback();
            callback.setCallbackUrl(callbackUrl);
            callback.setCallbackHost("oss-cn-hangzhou.aliyuncs.com");
            callback.setCallbackBody("{\\\"mimeType\\\":${mimeType},\\\"size\\\":${size}}");
            callback.setCalbackBodyType(CalbackBodyType.JSON);
            callback.addCallbackVar("x:var1", "value1");
            callback.addCallbackVar("x:var2", "value2");
            putObjectRequest.setCallback(callback);
            
            PutObjectResult putObjectResult = ossClient.putObject(putObjectRequest);
            byte[] buffer = new byte[1024];
            putObjectResult.getCallbackResponseBody().read(buffer);
            putObjectResult.getCallbackResponseBody().close();
            
            //上传一个新的文件
            //ossClient.putObject(new PutObjectRequest(bucketName, key, file));
            //上传文件流
            //ossClient.putObject(bucketName, key, inputStream);
            //上传字符串
            //String content = "Hello OSS";
            //ossClient.putObject(bucketName, key, new ByteArrayInputStream(content.getBytes()));
            //上传byte数组
            //byte[] contents = content.getBytes();
            //ossClient.putObject(bucketName, key, new ByteArrayInputStream(contents));
            //上传网络流
            //InputStream inputStream = new URL("https://www.aliyun.com/").openStream();
            //ossClient.putObject(bucketName, key, inputStream);
            //上传本地文件
            //ossClient.putObject(bucketName, key, new File("localFile"));
            
            //判断上传的object是否已经存入bucket
            boolean exists = ossClient.doesObjectExist(bucketName, key);
            log.error("Does object " + bucketName + " exist? " + exists);
            
            //可以自己设置bucket的权限
            ossClient.setObjectAcl(bucketName, key, CannedAccessControlList.PublicRead);
            ossClient.setObjectAcl(bucketName, key, CannedAccessControlList.Default);
            ObjectAcl objectAcl = ossClient.getObjectAcl(bucketName, key);
            log.error("ACL:" + objectAcl.getPermission().toString());
            
            //下载bucket中的内容
            //OSSObject实例包含文件所在的存储空间（Bucket）、文件的名称、Object Metadata以及一个输入流
            log.error("开始下载object");
            OSSObject object = ossClient.getObject(bucketName, key);
            log.error("Content-Type: "  + object.getObjectMetadata().getContentType());
            displayTextInputStream(object.getObjectContent());

            //查找bucket中对应前缀的文件
            ObjectListing objectListing = ossClient.listObjects(bucketName, "My");
            for (OSSObjectSummary objectSummary : objectListing.getObjectSummaries()) {
            	log.error(" - " + objectSummary.getKey() + "  " + "(size = " + objectSummary.getSize() + ")");
            }

            //删除一个object
            log.error("Deleting an object");
            ossClient.deleteObject(bucketName, key);
            
        } catch (OSSException oe) {
        	log.error("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
        	log.error("Error Message: " + oe.getErrorCode());
        	log.error("Error Code:       " + oe.getErrorCode());
        	log.error("Request ID:      " + oe.getRequestId());
        	log.error("Host ID:           " + oe.getHostId());
        } catch (ClientException ce) {
        	log.error("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
        	log.error("Error Message: " + ce.getMessage());
        } finally {
            //关闭ossClient
            ossClient.shutdown();
        }
    }

    private static void displayTextInputStream(InputStream input) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(input));
        while (true) {
            String line = reader.readLine();
            if (line == null){
            	break;
            } 
            log.error("    " + line);
        }
        reader.close();
    }
    
	
	public static String getFileNameAddTime(String fileName) {
		fileName = fileName.replaceAll(",", "");
		fileName = fileName.replaceAll("，", "");
		fileName = fileName.replaceAll("\\(", "");
		fileName = fileName.replaceAll("\\)", "");
		fileName = StringUtil.retainEnglishAndNumber(fileName);
		return System.currentTimeMillis() + HTTP_HENG + fileName + ".png";
	}

	public static String uploadImage(MultipartFile file, String folder, HttpServletRequest request) {
		String fileName = file.getOriginalFilename();
		String imgName = getFileNameAddTime(fileName);
		if(StringUtils.isBlank(folder)){
			return imgName;
		}
		return folder + HTTP_XIE + imgName;
	}
   
}
